home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 21 / Cream of the Crop 21 (Terry Blount) (October 1996).iso / program / libkb100.zip / LIBKB-1.00 / SRC / _KBLINUX.H < prev    next >
C/C++ Source or Header  |  1996-07-23  |  7KB  |  334 lines

  1. /* _kblinux.h -- Linux keyboard handler installation
  2.  * Copyright (C) Markus F.X.J. Oberhumer, Harm Hanemaayer and others
  3.  * For conditions of distribution and use, see copyright notice in kb.h 
  4.  */
  5.  
  6. /* WARNING: this file should *not* be used by applications. It is
  7.    part of the implementation of the keyboard library and is
  8.    subject to change. Applications should only use kb.h.
  9.  */
  10.  
  11.  
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14. #include <unistd.h>
  15. #include <fcntl.h>
  16. #include <termios.h>
  17. #include <sys/types.h>
  18. #include <sys/ioctl.h>
  19. #include <linux/kd.h>
  20. #include <linux/vt.h>
  21.  
  22.  
  23. /* IMPORTANT NOTE: you have to update the keyboard manually under Linux 
  24.  *                 !!! there are NO INTERRUPTS !!! 
  25.  *
  26.  * see also: svgalib 1.2.x: src/keyboard/keyboard.c
  27.  * see also: kbd 0.91: src/showkey.c
  28.  */
  29.  
  30.  
  31.  
  32. /***********************************************************************
  33. // keyboard handler 
  34. ************************************************************************/
  35.  
  36. #if defined(__i386__)
  37. #  undef KB_LINUX_MEDIUMRAW            /* use RAW mode */
  38. #else
  39. #  define KB_LINUX_MEDIUMRAW
  40. #endif
  41.  
  42. #include "_handler.h"
  43.  
  44.  
  45. /***********************************************************************
  46. // 
  47. ************************************************************************/
  48.  
  49. static int get_fd_info(int fd, int *mode, struct termios *t)
  50. {
  51.     int dummy_mode;
  52.     struct termios dummy_termios;
  53.  
  54.     if (fd < 0)
  55.         return -1;
  56.  
  57.     if (mode == NULL)
  58.         mode = &dummy_mode;
  59.     if (t == NULL)
  60.         t = &dummy_termios;
  61.  
  62.     if (ioctl(fd, KDGKBMODE, mode) != 0)
  63.     {
  64. #if defined(KB_DEBUG)
  65.         perror("libkb: cannot get keyboard mode");
  66. #endif
  67.         return -1;
  68.     }
  69. #if defined(KB_DEBUG) && (KB_DEBUG >= 2)
  70.     fprintf(stderr,"libkb info: fd: %d ioctl: kbmode=%d\n", fd, *mode);
  71. #endif
  72.  
  73.     if (tcgetattr(fd, t) != 0)
  74.     {
  75. #if defined(KB_DEBUG)
  76.         perror("libkb: tcgetattr");
  77. #endif
  78.         return -1;
  79.     }
  80. #if defined(KB_DEBUG) && (KB_DEBUG >= 2)
  81.     fprintf(stderr,"libkb info: fd: %d tcgetattr: iflag=0x%04lx "
  82.         "oflag=0x%04lx lflag=0x%04lx %d %d\n", 
  83.         fd, t->c_iflag, t->c_oflag, t->c_lflag, t->c_cc[VMIN], t->c_cc[VTIME]);
  84. #endif
  85.  
  86.     return 0;
  87. }
  88.  
  89.  
  90. /***********************************************************************
  91. // 
  92. ************************************************************************/
  93.  
  94. static int _my_kbd_fd = -1;
  95.  
  96. static int oldkbmode = K_XLATE;
  97. static struct termios oldkbdtermios;
  98.  
  99. static int keyboard_init_return_fd(void)
  100. {
  101.     int r = 0;
  102.     struct termios newkbdtermios;
  103.     struct vt_stat vtinfo;
  104.     int my_vt;
  105.     long first_non_opened;
  106.  
  107.  
  108. /* STEP 1a: open /dev/console */
  109.     if (_my_kbd_fd == -1)
  110.         _my_kbd_fd = open("/dev/console", O_RDONLY);
  111.     if (_my_kbd_fd == -1)
  112.     {
  113. #if defined(KB_DEBUG)
  114.         perror("libkb: cannot open /dev/console");
  115. #endif
  116.         return -1;
  117.     }
  118.     if (_my_kbd_fd < 0)
  119.     {
  120. #if defined(KB_DEBUG)
  121.         fprintf(stderr,"libkb: fd: %d, strange\n",_my_kbd_fd);
  122. #endif
  123.         return -1;
  124.     }
  125.  
  126.  
  127. /* STEP 1b: get current settings */
  128.     if (get_fd_info(_my_kbd_fd, &oldkbmode, &oldkbdtermios) != 0)
  129.         return -1;
  130. #if defined(KB_DEBUG) && (KB_DEBUG >= 2)
  131.     if (oldkbmode != K_XLATE)    /* what about K_UNICODE ? */
  132.         fprintf(stderr,"libkb info: keyboard not in K_XLATE, strange\n");
  133. #endif
  134.  
  135.  
  136. /* STEP 1c: get my VT info */
  137.     if (ioctl(_my_kbd_fd, VT_GETSTATE, &vtinfo) != 0)
  138.     {
  139. #if defined(KB_DEBUG)
  140.         perror("libkb: ioctl VT_GETSTATE");
  141. #endif
  142.         return -1;
  143.     }
  144.     else
  145.     {
  146. #if defined(KB_DEBUG) && (KB_DEBUG >= 2)
  147.         fprintf(stderr,"libkb info: fd: %d vt_stat: v_active=%d "
  148.             "v_signal=0x%x v_state=0x%x\n", _my_kbd_fd, (int) vtinfo.v_active,
  149.             (unsigned) vtinfo.v_signal, (unsigned) vtinfo.v_state);
  150. #endif
  151.     }
  152.     my_vt = vtinfo.v_active;
  153.  
  154.  
  155. /* STEP 1d: get number of virtual terminals */
  156.     if (ioctl(_my_kbd_fd, VT_OPENQRY, &first_non_opened) != 0)
  157.     {
  158. #if defined(KB_DEBUG)
  159.         perror("libkb: ioctl VT_OPENQRY");
  160. #endif
  161.         return -1;
  162.     }
  163.     else
  164.     {
  165. #if defined(KB_DEBUG) && (KB_DEBUG >= 2)
  166.         fprintf(stderr,"libkb info: first non opened VT: %ld\n",
  167.             first_non_opened);
  168. #endif
  169.     }
  170.     if (my_vt <= 0 || my_vt >= first_non_opened)
  171.     {
  172. #if defined(KB_DEBUG)
  173.         fprintf(stderr,"libkb: VT %d, first non opened VT: %ld\n",
  174.             my_vt, first_non_opened);
  175. #endif
  176.         return -1;
  177.     }
  178.  
  179.  
  180.  
  181.  
  182. /* STEP 2a: set new termios */
  183.     newkbdtermios = oldkbdtermios;
  184. #if 1
  185.     newkbdtermios.c_iflag = 0;
  186. #else
  187.     newkbdtermios.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON);
  188. #endif
  189.     newkbdtermios.c_lflag &= ~(ISIG | ICANON | ECHO);
  190.     /* Making these 0 seems to have the desired effect. */
  191.     newkbdtermios.c_cc[VMIN] = 0;
  192.     newkbdtermios.c_cc[VTIME] = 0;
  193.  
  194.     if (tcsetattr(_my_kbd_fd, TCSANOW, &newkbdtermios) != 0)
  195.     {
  196.         r = -2;
  197. #if defined(KB_DEBUG)
  198.         perror("libkb: tcsetattr");
  199. #endif
  200.     }
  201.  
  202.  
  203. /* STEP 2b: set new kbmode */
  204. #if defined(KB_LINUX_MEDIUMRAW)
  205.     if (ioctl(_my_kbd_fd, KDSKBMODE, K_MEDIUMRAW) != 0)
  206.     {
  207.         r = -2;
  208. #if defined(KB_DEBUG)
  209.         perror("libkb: ioctl KDSKBMODE K_MEDIUMRAW");
  210. #endif
  211.     }
  212. #else
  213.     if (ioctl(_my_kbd_fd, KDSKBMODE, K_RAW) != 0)
  214.     {
  215.         r = -2;
  216. #if defined(KB_DEBUG)
  217.         perror("libkb: ioctl KDSKBMODE K_RAW");
  218. #endif
  219.     }
  220. #endif
  221.  
  222.  
  223. /* all done */
  224.     if (r < 0)
  225.         return r;
  226. #if defined(KB_DEBUG) && (KB_DEBUG >= 2)
  227.     get_fd_info(_my_kbd_fd, NULL, NULL);    /* print the new settings */
  228. #endif
  229.     return _my_kbd_fd;    /* OK, return fd */
  230. }
  231.  
  232.  
  233. /***********************************************************************
  234. // 
  235. ************************************************************************/
  236.  
  237. static void _kb_remove(int final)
  238. {
  239.     int r = 0;
  240.  
  241.     if (_my_kbd_fd < 0)
  242.         return;
  243.  
  244. #if defined(KB_DEBUG)
  245.     fprintf(stderr,"_kb_remove 1: fd: %d  final: %d\n", _my_kbd_fd, final);
  246.     get_fd_info(_my_kbd_fd, NULL, NULL);    /* print the current settings */
  247. #endif
  248.  
  249.     if (ioctl(_my_kbd_fd, KDSKBMODE, oldkbmode) != 0)
  250.         r |= 1;
  251.     if (tcsetattr(_my_kbd_fd, 0, &oldkbdtermios) != 0)
  252.         r |= 2;
  253. #if defined(KB_DEBUG) && (KB_DEBUG >= 2)
  254.     get_fd_info(_my_kbd_fd, NULL, NULL);    /* print the current settings */
  255. #endif
  256.  
  257.     if (final)
  258.     {
  259.         if (close(_my_kbd_fd) != 0)
  260.             r |= 4;
  261.         _my_kbd_fd = -1;
  262.     }
  263.  
  264. #if defined(KB_DEBUG)
  265.     fprintf(stderr,"_kb_remove 2: fd: %d  error code: %d\n", _my_kbd_fd, r);
  266. #endif
  267. }
  268.  
  269.  
  270. static int _kb_install(void)
  271. {
  272.     int fd = keyboard_init_return_fd();
  273.     if (fd == -1)
  274.         return -1;
  275.     else if (fd < 0)
  276.     {
  277.         _kb_remove(1);
  278.         return -1;
  279.     }
  280.     else
  281.         return 0;
  282. }
  283.  
  284.  
  285. /***********************************************************************
  286. // update the keyboard
  287. ************************************************************************/
  288.  
  289. void kb_update(void)
  290. {
  291.     unsigned char buf[128];
  292.     int bytesread;
  293.     int vt = 0;
  294.  
  295.     if (!_kb_mode)
  296.         return;
  297.     
  298.     while ((bytesread = read(_my_kbd_fd, buf, sizeof(buf))) > 0)
  299.     {
  300.         int x;
  301.  
  302. #if defined(KB_LINUX_MEDIUMRAW)
  303.         x = _kb_linux_update(buf,bytesread,_my_mediumraw_handler);
  304. #else
  305.         x = _kb_linux_update(buf,bytesread,_my_raw_handler);
  306. #endif
  307.  
  308.         if (x > 0)
  309.             vt = x;
  310.  
  311.         /* Control-C check */
  312.         if (_kb_flags & KB_FLAG_SIGINT)
  313.         {
  314.             if (_kb_key[KB_SCAN_C] && 
  315.                 (_kb_key[KB_SCAN_LCONTROL] || _kb_key[KB_SCAN_RCONTROL]))
  316.                 raise(SIGINT);
  317.         }
  318.     }
  319.  
  320.  
  321.     if (vt > 0)
  322.         _kb_linux_switch_vt(_my_kbd_fd,vt);
  323.     
  324.  
  325.     if (_kb_flags & KB_FLAG_EMERGENCY_SIGALRM)
  326.         _kb_signal_alarm_update();
  327. }
  328.  
  329.  
  330. /*
  331. vi:ts=4
  332. */
  333.  
  334.